package org.dbstar.scheduler.quartz;

import java.util.Map;

import org.dbstar.scheduler.control.JobController;
import org.dbstar.scheduler.identifier.Identifier;
import org.dbstar.scheduler.identifier.IdentifierType;
import org.dbstar.scheduler.job.JobStatus;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 用于Retry Job
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-5-28
 */
public class RetryJob implements Job {
	private static final Logger LOGGER = LoggerFactory.getLogger(RetryJob.class);

	public static final String JOB_PARAMETERS_KEY = "job.parameters";

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		try {
			SchedulerContext schedulerContext = context.getScheduler().getContext();
			JobDataMap dataMap = context.getMergedJobDataMap();

			JobController controller = getObject(schedulerContext, JobController.class, null);
			Identifier identifier = getObject(dataMap, Identifier.class, '.' + IdentifierType.job.name());

			org.dbstar.scheduler.beans.Job job = controller.getJob(identifier);
			if (job != null && job.getStatus() == JobStatus.retry) {
				LOGGER.debug("Retry job: {}", identifier.getStringIdentifier());
				controller.changeJobStatus(identifier, JobStatus.ready);
			}
		} catch (Exception e) {
			LOGGER.error("执行调度任务失败：" + context.getTrigger().getKey(), e);
		}
	}

	@SuppressWarnings("unchecked")
	private <T> T getObject(Map<String, Object> context, Class<T> clazz, String suffix) throws JobExecutionException {
		T obj;
		try {
			obj = (T) context.get(clazz.getName() + (suffix == null ? "" : suffix));
		} catch (Throwable e) {
			throw new JobExecutionException("Get " + clazz.getSimpleName() + " faild.", e);
		}
		if (obj == null) {
			throw new JobExecutionException("Get " + clazz.getSimpleName() + " faild. Object not set.");
		}
		return obj;
	}
}
